<!--
 * @Author: wangming
 * @Date: 2020-09-07 10:01:43
 * @LastEditors: wangming
 * @LastEditTime: 2022-04-29 16:58:26
 * @Description: 新增表单模板通用导航
-->

<template>
  <div class="get_form bgwh">
    <div class="ks-row-middle-between pl24 pr24 formnav bgwh sz">
      <template>
        <el-button size="small" @click="getback()" v-if="getNavName !== 'home'">
          返回设计
        </el-button>
        <el-button @click="back" v-else> 关闭 </el-button>
      </template>
      <div class="g3 f16 b ks-col ml20">
        {{ getTemplateDate.name ? `模态框(${getTemplateDate.name})` : title }}
        <div class="ml10 f12 nowrap dib" v-if="getTemplateDate.name">
          <span class="b mr10"> {{ getTemplateDate.key }}</span>
          <el-button
            type="text"
            @click="copy(getTemplateDate.key)"
            icon="el-icon-document-copy"
          ></el-button>
        </div>
      </div>
      <template v-if="getNavName === 'home'">
        <el-button
          size="small"
          type="text"
          v-if="!!lockBy"
          @click="locked(false)"
        >
          <div class="ks-row-middle lh0">
            <i class="iconfont iconicon_suoguan_gaoliang f16 mr5"></i>
            <span>已锁定</span>
          </div>
        </el-button>
        <el-button size="small" type="text" v-else @click="locked(true)">
          <div class="ks-row-middle lh0">
            <i class="iconfont iconicon_suokai f16 mr5"></i>
            <span>锁定</span>
          </div>
        </el-button>
        <el-button size="small" type="text" @click="$emit('goPreview')">
          <div class="ks-row-middle">
            <i class="el-icon-view f18"></i>
            <span>预览</span>
          </div>
        </el-button>
        <el-button size="small" type="text" @click="save">
          <div class="ks-row-middle">
            <i class="el-icon-upload f18"></i>
            <span>保存</span>
          </div>
        </el-button>
        <el-button size="small" type="text" @click="$emit('setting')">
          <div class="ks-row-middle">
            <i class="el-icon-setting f18"></i>
            <span>全局设置</span>
          </div>
        </el-button>
        <el-button size="small" type="text" @click="setAuth">
          <div class="ks-row-middle">
            <i class="el-icon-set-up f18"></i>
            <span>权限设置</span>
          </div>
        </el-button>
      </template>
      <el-button
        size="small"
        type="text"
        v-if="getNavName === 'template'"
        @click="setFormTem"
      >
        <div class="ks-row-middle">
          <i class="el-icon-setting f18"></i>
          <span>全局设置</span>
        </div>
      </el-button>
    </div>
    <slot></slot>
  </div>
</template>
<script>
import commonModule from "./commonModule";
import { mapActions, mapGetters } from "vuex";
import { isEqual, cloneDeep } from "lodash";

import dialogModule from "./dialogModule/index.js";
import authModule from "./authModule/index.js";
import {
  postHmpageLock,
  postHmpageUnlock,
} from "@/apis/paas/HmPageController.js";
import {
  postPagepermissionconfig,
  getPagepermissionconfigControlledpermissions,
} from "@/apis/paas/HmPagePermissionItemController.js";
import { tagsParse } from "@/components/HmPermission";
import { copy } from "@/utils/util";
export default {
  data() {
    return {
      oldjson: {},
      authList: [],
      timer: null,
      mergeNameByIds: {}, // 合并id重复按钮名字
    };
  },
  computed: {
    ...mapGetters([
      "getFormData",
      "getNavName",
      "getUserVal",
      "getTemplateDate",
    ]),
  },
  async mounted() {
    await this.$nextTick();
    const { id } = this.getUserVal;
    if (this.lockBy === id || !this.lockBy) {
      this.autoSave();
    }
  },
  destroyed() {
    clearInterval(this.timer);
  },
  props: ["title", "lockBy", "formList"],
  methods: {
    getback() {
      this.setNavName("home");
    },
    copy,
    ...mapActions(["setNavName"]),
    autoSave() {
      clearInterval(this.timer);
      this.timer = setInterval(() => {
        const insave = isEqual(
          {
            formList: this.formList,
            FormData: this.getFormData,
          },
          this.oldjson
        );
        if (insave) return;
        this.cloneJSON();
        this.$emit("save", true);
      }, 300000);
    },
    async setAuth() {
      const pageId = this.$route.query.id;
      this.authList = await getPagepermissionconfigControlledpermissions({
        pageId,
      });
      const { formList, FormData } = this.oldjson;
      if (!formList) {
        this.$message.info("请先保存表单！");
        return;
      }
      this.mergeNameByIds = {};
      const { btnList } = this.getLayoutTreeToArg(formList, FormData);
      const template = FormData.template.map((tep) => {
        const { btnList } = this.getLayoutTreeToArg(tep.formList, tep.FormData);
        return { btnList, name: tep.name, key: tep.key };
      });
      template.forEach(({ btnList }) => this.changeNewName(btnList));
      this.changeNewName(btnList);
      authModule
        .openForm(cloneDeep({ btnList, template }))
        .then(async (permissionItems) => {
          await postPagepermissionconfig({ pageId, permissionItems });
          this.$message.success("操作成功");
        });
    },
    changeNewName(btnList) {
      btnList.forEach((i) => {
        const arg = this.mergeNameByIds[i.componentId];
        if (arg) i.name = arg.join(",");
        if (i?.children?.length > 0) {
          this.changeNewName(i.children);
        }
      });
    },
    // 遍历form树获取想要的权限单元
    getLayoutTreeToArg(formList, FormData) {
      const btnList = [];
      let queen = this.getLayoutList(formList, FormData);
      while (queen.length) {
        const first = queen.shift();
        if (first.children) {
          queen = [].concat(first.children, queen);
        }
        this.transformFormList(first, btnList, FormData.key);
      }
      return { btnList };
    },
    getLayoutList(formList, FormData) {
      // 根据页面布局情况获取list
      let list = [].concat(formList);
      const { type, Footer, Aside } = FormData.layout;
      if (type === "lrcontainer" || type === "tbcontainer") {
        list = list.concat(Aside);
      } else if (type === "ltbcontainer") {
        list = list.concat(Aside, Footer);
      }
      return list;
    },
    getCheckedForAuth(componentId) {
      return this.authList.find((i) => {
        let arg = i.componentId.split(":");
        if (arg.length === 1) {
          return i.componentId === componentId.split(":")[1];
        } else {
          return i.componentId === componentId;
        }
      });
    },
    transformFormList(i, tagList, FormDataKey) {
      // 按钮组
      if (i.tagName === "hlcustomBtn") {
        this.transformCustomBtn(i.children, tagList, FormDataKey);
      }
      if (i.tagName === "hlChildTb") {
        this.transformCustomBtn(i.hlcustomBtn.children, tagList, FormDataKey);
      }
      // 表格逻辑
      if (
        i.tagName === "hlTableList" ||
        i.tagName === "hlTableForRelation" ||
        i.tagName === "hlTableForChildren"
      ) {
        const table = {
          type: "table",
          name: "表格",
          alias: "",
          componentId: i.key,
          children: [],
        };
        // 按钮组
        this.transformCustomBtn(
          i.hlcustomBtn.children,
          table.children,
          FormDataKey
        );
        const {
          btnList = [],
          hide,
          isRender,
          customBtn = [],
        } = i.__config.operate;
        // 操作组
        if (!hide && !isRender) {
          this.transformTableListForOperate(
            btnList,
            `${FormDataKey}:${i.key}`,
            table.children
          );
          this.transformTableListForOperateCustom(
            customBtn,
            table.children,
            FormDataKey
          );
        }
        //子表场景
        if (!!i.hlChildTable) {
          const { hide, isRender, customBtn = [] } = i.hlChildTable.operate;
          !hide &&
            !isRender &&
            this.transformTableListForOperateCustom(
              customBtn,
              table.children,
              FormDataKey
            );
        }
        // 自定义按钮
        this.transformJsxBtn(JSON.stringify(i), table.children, FormDataKey);
        table.children.length > 0 && tagList.push(table);
      } else {
        // 自定义按钮
        this.transformJsxBtn(
          i?.__config?.renderJsx || "",
          tagList,
          FormDataKey
        );
      }
    },
    merageKeys(key, name) {
      const label = this.mergeNameByIds[key];
      if (label) {
        this.mergeNameByIds[key].push(name);
        return true;
      } else {
        this.mergeNameByIds[key] = [name];
        return false;
      }
    },
    // 自定义jsx组件解析
    transformJsxBtn(str, list, FormDataKey) {
      tagsParse(decodeURIComponent(str)).forEach((k) => {
        let componentId = FormDataKey + ":" + k.id;
        if (this.merageKeys(componentId, k.name)) return;
        const item = this.getCheckedForAuth(componentId);
        list.push({
          alias: item?.alias || k.name,
          componentId,
          componentType: "Button",
          name: k.name,
          checked: !!item,
        });
      });
    },
    // 按钮解析
    transformCustomBtn(children, list, FormDataKey) {
      children.forEach((j) => {
        let componentId = FormDataKey + ":" + j.key;
        if (this.merageKeys(componentId, j.name)) return;
        const item = this.getCheckedForAuth(componentId);
        list.push({
          alias: item?.alias || j.name,
          componentId,
          componentType: "Button",
          name: j.name,
          checked: !!item,
        });
      });
    },
    // table操作解析
    transformTableListForOperate(children, key, list) {
      children
        .filter((i) => i.show)
        .map((j) => {
          const componentId = key + "-" + j.handler;
          if (this.merageKeys(componentId, j.label)) return;
          const item = this.getCheckedForAuth(componentId);
          list.push({
            alias: item?.alias || j.label,
            componentId,
            componentType: "Button",
            name: j.label,
            checked: !!item,
          });
        });
    },
    // table自定义操作解析
    transformTableListForOperateCustom(children, list, FormDataKey) {
      children.map((j) => {
        const componentId = FormDataKey + ":" + j.composerKey;
        if (this.merageKeys(componentId, j.label)) return;
        const item = this.getCheckedForAuth(componentId);
        list.push({
          alias: item?.alias || j.label,
          componentId,
          componentType: "Button",
          name: j.label,
          checked: !!item,
        });
      });
    },
    cloneJSON() {
      setTimeout(() => {
        // 等部分组件初始化完成后在复制
        this.oldjson = cloneDeep({
          formList: this.formList,
          FormData: this.getFormData,
        });
      }, 200);
    },
    save() {
      this.cloneJSON();
      this.$emit("save");
      this.autoSave();
    },
    async back() {
      const newjson = {
        formList: this.formList,
        FormData: this.getFormData,
      };
      const { id } = this.getUserVal;
      const islock = this.lockBy !== id;
      const insave = isEqual(newjson, this.oldjson);
      if (islock && insave) {
        this.$router.go(-1);
        return;
      }
      dialogModule.openModule({ islock, insave }).then((res) => {
        switch (res) {
          case "b":
            this.save();
            break;
          case "c":
            this.locked(false);
            break;
          case "d":
            this.save();
            this.locked(false);
            break;
          default:
            break;
        }
        this.$router.go(-1);
      });
    },
    setFormTem() {
      commonModule.openForm(this.getTemplateDate).then((res) => {
        Object.assign(this.getTemplateDate, res);
      });
    },
    async locked(flag) {
      const { id } = this.getUserVal;
      if (flag) {
        const newjson = {
          formList: this.formList,
          FormData: this.getFormData,
        };
        const insave = isEqual(newjson, this.oldjson);
        if (!insave) {
          try {
            await this.$confirm("页面未保存", {
              title: "提示",
              type: "warning",
              cancelButtonText: "继续锁定",
              confirmButtonText: "保存后锁定",
              showClose: false,
            });
            this.save();
          } catch (error) {}
        }
        await postHmpageLock({ id: this.$route.query.id });
        this.$message.success("锁定成功");
        this.$emit("update:lockBy", id);
      } else {
        await postHmpageUnlock({ id: this.$route.query.id });
        this.$message.success("解锁成功");
        this.$emit("update:lockBy", "");
      }
    },
  },
};
</script>
<style lang="scss" scoped>
.get_form {
  height: 100%;
}
.formnav {
  height: 64px;
  box-shadow: 0px 1px 4px 0px rgba(0, 21, 41, 0.12);
  position: fixed;
  top: 0;
  width: 100%;
  z-index: 1000;
}
</style>
